package com.example.javaproject.design.rules;


import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * ### 里氏替换原则
 * <p>
 * 1、父类出现的地方，子类一定可以替代它出现，反之不然；
 * 另外一层含义就是 子类可以扩展父类的功能，但不能改变父类原有的功能；
 * 2、里氏替换原则是实现"开闭原则"的重要手段，强调的是 子类与父类的关系，当有需求变化时，不希望去修改父类的原有功能，可以子类去实现新功能，或者给父类添加新的抽象方法
 * </p>
 */
public class LSPTest {

    public static void main(String[] args) {
        Father father = new Son();
        HashMap<String, String> map = new HashMap<>();
        father.doSomething(map);

        // 这里明显看出，b类去复写了父类的非抽象方法，造成语意上的错误，类似这种一般处理方案是将 父类中不希望子类复写的方法定义成final或者 子类不要去复写父类的非抽象方法
        A a = new A();
        System.out.println("5+2的结果为：" + a.fun1(5, 2));
        A a1 = new B();
        System.out.println("5+2的结果为：" + a1.fun1(5, 2));
    }
}

//父类
class Father {
    public Collection<String> doSomething(HashMap<String, String> map) {
        System.out.println("父类被执行");
        return map.values();
    }
}

//子类
class Son extends Father {
    @Override
    public Collection<String> doSomething(HashMap<String, String> map) {
        System.out.println("子类被执行");
        return map.values();
    }

    public Collection<String> doSomething(Map<String, String> map) {
        System.out.println("子类被执行");
        return map.values();
    }
}

/**
 * 类a完成2个数相加
 */
class A {

    public int fun1(int a, int b) {
        return a + b;
    }
}

/**
 * 子类B继承A,覆写fun1将"fun1"意义变成了2个数相减
 */
class B extends A {
    public int fun1(int a, int b) {
        return a - b;
    }
}


